package com.base.storage.provider;

import com.base.core.codec.Base64Utils;
import com.base.core.lang.StringUtils;
import com.base.storage.enums.BusinessCodeEnums;
import com.base.storage.service.CloudStorageService;
import com.base.core.exception.ServiceException;
import com.base.core.utils.IOUtils;
import com.base.storage.config.CloudStorageConfig;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.Base64;

/**
 * 服务器存储
 */
public class DiskCloudStorageService extends CloudStorageService {


    public DiskCloudStorageService(CloudStorageConfig cloudStorageConfig) {
        super(cloudStorageConfig);
    }

    /**
     * 文件上传
     *
     * @param file 文件
     * @return 返回http地址
     */
    @Override
    public String upload(MultipartFile file) throws Exception {
        if (file == null) {
            throw new ServiceException(BusinessCodeEnums.FILE_NOT_EXISTS, BusinessCodeEnums.FILE_NOT_EXISTS.getMessage());
        }

        //检查文件合法性
        if(!this.checkSize(file)){
            throw new ServiceException(BusinessCodeEnums.FILE_SIZE_LIMIT, BusinessCodeEnums.FILE_SIZE_LIMIT.getMessage());
        }

        if(!this.checkType(file)){
            throw new ServiceException(BusinessCodeEnums.FILE_TYPE_ILLEGAL, BusinessCodeEnums.FILE_TYPE_ILLEGAL.getMessage());
        }

        //文件名称
        String oldName = file.getOriginalFilename();
        //文件后缀
        String postfix = oldName.substring(oldName.lastIndexOf(".") + 1);

        //新文件名
        String fileName = getPath(config.getDstPrefix()) + "." + postfix;

        //本地存储必需要以"/"开头
        if (!fileName.startsWith("/")) {
            fileName = "/" + fileName;
        }
        try {
            String dateDir = fileName.split("/")[1];
            //文件夹
            File dirFile = new File(config.getDiskPath() + "/" + dateDir);
            if (!dirFile.exists()) {
                dirFile.mkdirs();
            }
            File dstFile = new File(config.getDiskPath() + fileName);
            file.transferTo(dstFile);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("上传文件失败", e);
        }

        return config.getProxyServer() + fileName;

    }

    public String upload(String base64) {
        if (StringUtils.isEmpty(base64)) {
            throw new ServiceException(BusinessCodeEnums.FILE_NOT_EXISTS, BusinessCodeEnums.FILE_NOT_EXISTS.getMessage());
        }
        // 文件格式: "data:image/png;base64," + "图片的base64字符串"
        MultipartFile files = Base64Utils.base64ToMultipart(base64);
        //检查文件合法性
        if(!this.checkSize(files)){
            throw new ServiceException(BusinessCodeEnums.FILE_SIZE_LIMIT, BusinessCodeEnums.FILE_SIZE_LIMIT.getMessage());
        }

        if(!this.checkType(files)){
            throw new ServiceException(BusinessCodeEnums.FILE_TYPE_ILLEGAL, BusinessCodeEnums.FILE_TYPE_ILLEGAL.getMessage());
        }

        //老文件名
        String oldName = files.getOriginalFilename();

        //文件后缀
        String postfix = oldName.substring(oldName.lastIndexOf(".") + 1);
        //新文件名
        String fileName = getPath(config.getDstPrefix()) + "." + postfix;

        //本地存储必需要以"/"开头
        if (!fileName.startsWith("/")) {
            fileName = "/" + fileName;
        }

        try {
            String dateDir = fileName.split("/")[1];

            //文件夹
            File dirFile = new File(config.getDiskPath() + "/" + dateDir);
            if (!dirFile.exists()) {
                dirFile.mkdirs();
            }
            File dstFile = new File(config.getDiskPath() + fileName);
            files.transferTo(dstFile);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("上传文件失败", e);
        }

        return config.getProxyServer() + fileName;
    }

    public String upload(String base64, String filename) {
        if (StringUtils.isEmpty(base64)) {
            throw new ServiceException(BusinessCodeEnums.FILE_NOT_EXISTS, BusinessCodeEnums.FILE_NOT_EXISTS.getMessage());
        }
        // 文件格式: "data:image/png;base64," + "图片的base64字符串"
        MultipartFile files = Base64Utils.base64ToMultipart(base64);
        //检查文件合法性
        if(!this.checkSize(files)){
            throw new ServiceException(BusinessCodeEnums.FILE_SIZE_LIMIT, BusinessCodeEnums.FILE_SIZE_LIMIT.getMessage());
        }

        if(!this.checkType(files)){
            throw new ServiceException(BusinessCodeEnums.FILE_TYPE_ILLEGAL, BusinessCodeEnums.FILE_TYPE_ILLEGAL.getMessage());
        }

        //老文件名
        String oldName = files.getOriginalFilename();

        //文件后缀
        String postfix = oldName.substring(oldName.lastIndexOf(".") + 1);
        //新文件名
        String fileName = getPath(config.getDstPrefix(),filename) + "." + postfix;

        //本地存储必需要以"/"开头
        if (!fileName.startsWith("/")) {
            fileName = "/" + fileName;
        }

        try {
            String dateDir = fileName.split("/")[1];

            //文件夹
            File dirFile = new File(config.getDiskPath() + "/" + dateDir);
            if (!dirFile.exists()) {
                dirFile.mkdirs();
            }
            File dstFile = new File(config.getDiskPath() + fileName);
            files.transferTo(dstFile);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("上传文件失败", e);
        }

        return config.getProxyServer() + fileName;
    }

    /**
     * 文件上传
     *
     * @param inputStream 字节流
     * @param fileType 文件类型
     * @param path        文件路径，包含文件名
     * @return 返回http地址
     */
    @Override
    protected String upload(InputStream inputStream, String fileType, String path) {
        try {
            byte[] data = IOUtils.toByteArray(inputStream);
            String base64 = Base64.getEncoder().encodeToString(data);
            return this.upload(base64);
        } catch (IOException e) {
            throw new ServiceException("上传文件失败", e);
        }
    }

    /**
     * 通过文件名下载文件
     *
     * @param fileName      要下载的文件名
     *                      例如：4DB049D0604047989183CB68D76E969D.jpg
     * @param localFileName 本地要创建的文件名
     */
    @Override
    public void downloadFile(String fileName, String localFileName) {

    }

    /**
     * @param fileUrl 需要删除的文件url
     * @return boolean 是否删除成功
     * @MethodName: deleteFile
     * @Description: 单文件删除
     * 例如：http://*.oss-cn-beijing.aliyuncs.com/4DB049D0604047989183CB68D76E969D.jpg
     */
    @Override
    public boolean deleteFile(String fileUrl) {
        return false;
    }
}
